package v1

import (
	"fmt"
	"gitee.com/CrazyMage/blog-service/global"
	"gitee.com/CrazyMage/blog-service/internal/service"
	"gitee.com/CrazyMage/blog-service/pkg/ai"
	"gitee.com/CrazyMage/blog-service/pkg/app"
	"gitee.com/CrazyMage/blog-service/pkg/errcode"
	"github.com/cloudwego/eino/schema"
	"github.com/gin-gonic/gin"
	"io"
	"log"
	"strings"
)

type Ai struct {
}

func NewAi() Ai {
	return Ai{}
}

func (a Ai) Chat(c *gin.Context) {

	//1.构建参数和返回类型
	param := service.BlockingChatRequest{}
	response := app.NewResponse(c)

	//2.绑定参数
	valid, errs := app.BindAndValid(c, &param)
	if !valid {
		global.Logger.Errorf(c, "app.BindAndValid errs: %v", errs)
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}

	//3.创建服务
	svc := service.New(c.Request.Context())

	//4.调用服务
	content, err := svc.BlockingChat(&param)
	if err != nil {
		global.Logger.Errorf(c, "svc.BlockingChat err: %v", err)
		log.Println(err)
		return
	}

	//5.返回结果
	response.ToResponse(content)
	return

}

func (a Ai) StreamingChat(c *gin.Context) {

	//1.构建参数和返回类型
	param := service.StreamingChatRequest{}
	response := app.NewResponse(c)

	//2.绑定参数
	valid, errs := app.BindAndValid(c, &param)
	if !valid {
		global.Logger.Errorf(c, "app.BindAndValid errs: %v", errs)
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}

	//3.创建服务
	svc := service.New(c.Request.Context())

	//4.调用服务
	sr, err := svc.StreamingChat(&param)
	if err != nil {
		global.Logger.Errorf(c, "svc.BlockingChat err: %v", err)
		log.Println(err)
		return
	}

	//流式输出
	res := streamingOut(c, sr)
	chatMemory := ai.NewRedisChatMemory(c)
	err = chatMemory.AddSingleMessage(param.ConversationId, &ai.Message{
		Role:    "assistant",
		Content: res,
	})
	if err != nil {
		return
	}

	return
}

func streamingOut(c *gin.Context, sr *schema.StreamReader[*schema.Message]) string {

	// 设置SSE响应头
	c.Header("Content-Type", "text/event-stream")
	c.Header("Cache-Control", "no-cache")
	c.Header("Connection", "keep-alive")
	c.Header("Access-Control-Allow-Origin", "*")

	//关闭流
	defer sr.Close()

	// 流式传输
	i := 0
	var builder strings.Builder
	c.Stream(func(w io.Writer) bool {
		message, err := sr.Recv()
		if err == io.EOF {
			return false
		}
		if err != nil {
			log.Printf("recv failed: %v", err)
			return false
		}
		builder.WriteString(message.Content)
		// 发送事件
		c.SSEvent(fmt.Sprintf("message[%d]:", i), message.Content)
		i++
		return true
	})

	return builder.String()

}
